package com.rzcoding.service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rzcoding.dao.CategoryMapper;
import com.rzcoding.dto.base.ResultConst;
import com.rzcoding.dto.dao.CategoryLevelMo;
import com.rzcoding.dto.dao.CategoryLevelOneIdMo;
import com.rzcoding.dto.resp.CategoryRespMo;
import com.rzcoding.entity.Category;
import com.rzcoding.exception.BussinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    private List<CategoryRespMo> buildCategoryRespMo(List<CategoryLevelMo> levelMos){
        Map<Integer, CategoryRespMo> levelOneRespMoMap = new HashMap<>();
        Map<Integer, CategoryRespMo> levelTwoRespMoMap = new HashMap<>();
        for (CategoryLevelMo levelMo : levelMos) {
            Integer id = levelMo.getId();
            if(!levelOneRespMoMap.containsKey(id)){
                CategoryRespMo categoryLevelOneRespMo = new CategoryRespMo();
                categoryLevelOneRespMo.id = id;
                categoryLevelOneRespMo.catName = levelMo.getCatName();
                categoryLevelOneRespMo.level = levelMo.getLevel();
                categoryLevelOneRespMo.pid = levelMo.getPid();
                levelOneRespMoMap.put(levelMo.getId(), categoryLevelOneRespMo);

                if(levelMo.getC2Id() != null){
                    CategoryRespMo categoryLevelTwoRespMo = new CategoryRespMo();
                    categoryLevelTwoRespMo.id = levelMo.getC2Id();
                    categoryLevelTwoRespMo.catName = levelMo.getC2CatName();
                    categoryLevelTwoRespMo.level = levelMo.getC2Level();
                    categoryLevelTwoRespMo.pid = levelMo.getC2Pid();
                    levelTwoRespMoMap.put(levelMo.getC2Id(), categoryLevelTwoRespMo);

                    if(CollectionUtils.isEmpty(categoryLevelOneRespMo.children)){
                        categoryLevelOneRespMo.children = new ArrayList<>();
                    }
                    categoryLevelOneRespMo.children.add(categoryLevelTwoRespMo);
                    if(levelMo.getC3Id() != null){
                        CategoryRespMo categoryLevelThreeRespMo = new CategoryRespMo();
                        categoryLevelThreeRespMo.id = levelMo.getC3Id();
                        categoryLevelThreeRespMo.catName = levelMo.getC3CatName();
                        categoryLevelThreeRespMo.level = levelMo.getC3Level();
                        categoryLevelThreeRespMo.pid = levelMo.getC3Pid();

                        if(CollectionUtils.isEmpty(categoryLevelTwoRespMo.children)){
                            categoryLevelTwoRespMo.children = new ArrayList<>();
                        }
                        categoryLevelTwoRespMo.children.add(categoryLevelThreeRespMo);
                    }
                }
            }else{
                CategoryRespMo categoryLevelOneRespMo = levelOneRespMoMap.get(levelMo.getId());
                if(levelMo.getC2Id() != null){
                    CategoryRespMo categoryLevelTwoRespMo = levelTwoRespMoMap.get(levelMo.getC2Id());
                    if(null == categoryLevelTwoRespMo){
                        categoryLevelTwoRespMo = new CategoryRespMo();
                        categoryLevelTwoRespMo.id = levelMo.getC2Id();
                        categoryLevelTwoRespMo.catName = levelMo.getC2CatName();
                        categoryLevelTwoRespMo.level = levelMo.getC2Level();
                        categoryLevelTwoRespMo.pid = levelMo.getC2Pid();
                        levelTwoRespMoMap.put(levelMo.getC2Id(), categoryLevelTwoRespMo);
                    }

                    if(levelMo.getC3Id() != null){
                        CategoryRespMo categoryLevelThreeRespMo = new CategoryRespMo();
                        categoryLevelThreeRespMo.id = levelMo.getC3Id();
                        categoryLevelThreeRespMo.catName = levelMo.getC3CatName();
                        categoryLevelThreeRespMo.level = levelMo.getC3Level();
                        categoryLevelThreeRespMo.pid = levelMo.getC3Pid();

                        if(CollectionUtils.isEmpty(categoryLevelTwoRespMo.children)){
                            categoryLevelTwoRespMo.children = new ArrayList<>();
                        }
                        categoryLevelTwoRespMo.children.add(categoryLevelThreeRespMo);
                    }

                    boolean exist = false;
                    for (CategoryRespMo levelOneChild : categoryLevelOneRespMo.children) {
                        if(Objects.equals(levelOneChild.getId(), levelMo.getC2Id())){
                            exist = true;
                        }
                    }
                    if(!exist){
                        if(CollectionUtils.isEmpty(categoryLevelOneRespMo.children)){
                            categoryLevelOneRespMo.children = new ArrayList<>();
                        }
                        categoryLevelOneRespMo.children.add(categoryLevelTwoRespMo);
                    }
                }
            }

        }
        List<CategoryRespMo> categoryRespMoList = new ArrayList<>();
        for (Map.Entry<Integer,CategoryRespMo> categoryRespMoEntry : levelOneRespMoMap.entrySet()) {
            categoryRespMoList.add(categoryRespMoEntry.getValue());
        }
        return categoryRespMoList;
    }


    public JSONObject findPage(int pageNum, int pageSize, Integer type){
        List<CategoryRespMo> categoryRespMoList = null;
        long total = 0;
        if(type == 2){
            List<CategoryLevelMo> levelMos = categoryMapper.selectLevelTwo();
            if(CollectionUtils.isNotEmpty(levelMos)){
                categoryRespMoList = buildCategoryRespMo(levelMos);
                total = categoryRespMoList.size();
            }
        }else if(type == 3){
            //分页
            PageHelper.startPage(pageNum,pageSize);
            List<CategoryLevelOneIdMo> categoryLevelOneIdMos = categoryMapper.selectLevelOneIds();
            PageInfo<CategoryLevelOneIdMo> pageInfo = new PageInfo<>(categoryLevelOneIdMos);
            total = pageInfo.getTotal();
            if(total != 0){
                List<Integer> ids = categoryLevelOneIdMos.stream().map(CategoryLevelOneIdMo::getId).collect(Collectors.toList());
                List<CategoryLevelMo> levelMos = categoryMapper.selectLevelThreeByIds(ids);
                categoryRespMoList = buildCategoryRespMo(levelMos);
            }
        }else{
            throw new BussinessException(HttpStatus.FORBIDDEN.value(), ResultConst.INVALID_TYPE);
        }
        JSONObject resp = new JSONObject().fluentPut("total", total);
        resp.put("result", categoryRespMoList);
        return resp;
    }


    /**
     * 删除
     * @param id
     */
    public void delete(Integer id){
        categoryMapper.deleteByPrimaryKey(id);
    }

    /**
     * 修改Category
     * @param category
     */
    public void update(Category category){
        category.setLevel(null);
        category.setPid(null);
        categoryMapper.updateByPrimaryKeySelective(category);
    }

    /**
     * 增加Category
     * @param category
     */
    public void add(Category category){
        category.setId(null);
        categoryMapper.insertSelective(category);
    }

    /**
     * 根据ID查询Category
     * @param id
     * @return
     */
    public Category findById(Integer id){
        return  categoryMapper.selectByPrimaryKey(id);
    }

}
